package com.lau.controller;


import cn.hutool.core.bean.BeanUtil;
import com.lau.common.annotation.OperationLog;
import com.lau.common.dto.PassDto;
import com.lau.common.enums.OperationTypeEnum;
import com.lau.common.enums.ResultStatusEnum;
import com.lau.common.exception.DebugException;
import com.lau.common.lang.Const;
import com.lau.common.lang.Result;
import com.lau.entity.SysRole;
import com.lau.entity.SysUser;
import com.lau.entity.SysUserRole;
import com.lau.vo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Lau
 * @since 2023-11-08
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController extends BaseController {

	@Autowired
	BCryptPasswordEncoder passwordEncoder;

	@Value("${lau.default.password}")
	private String defaultPassword;


	/**
	 * 根据用户id查询用户信息
	 * @param id 用户id
	 * @return 用户基本信息
	 */
	@GetMapping("/info/{id}")
	@PreAuthorize("hasAuthority('sys:user:list')")
	@OperationLog(event = "查询用户信息",operType = OperationTypeEnum.QUERY)
	public Result info(@PathVariable("id") Long id) {

		SysUser sysUser = sysUserService.getById(id);
		if(sysUser==null){
			throw new DebugException(ResultStatusEnum.USERNOTEXIST);
		}
		List<SysRole> roles = sysRoleService.listRolesByUserId(id);
		User user = new User();
		BeanUtil.copyProperties(sysUser,user);
		user.setSysRoles(roles);
		return Result.succ(user);
	}

	/**
	 * 查询用户列表
	 * @param username 用户名（可有可无）
	 * @param page 分页
	 * @return 用户列表
	 */
	@GetMapping("/list")
	@PreAuthorize("hasAuthority('sys:user:list')")
	@OperationLog(event = "查询用户列表",operType = OperationTypeEnum.QUERY)
	public Result list(String username,Page page) {
		Page pageData = sysUserService.pageUserByUserName(page, username);
		return Result.succ(pageData);
	}

	@PostMapping("/save")
	@PreAuthorize("hasAuthority('sys:user:save')")
	@OperationLog(event = "新增用户",operType = OperationTypeEnum.ADD)
	public Result save(@Validated @RequestBody SysUser sysUser) {
		// 默认密码
		String password = passwordEncoder.encode(defaultPassword);
		sysUser.setPassword(password);
		// 默认头像
		sysUser.setAvatar(Const.DEFULT_AVATAR);

		sysUserService.save(sysUser);
		sysUser.setPassword(null);
		return Result.succ(sysUser);
	}

	/**
	 * 更新用户信息
	 * @param sysUser 被更新的用户信息
	 * @return
	 */
	@PostMapping("/update")
	@PreAuthorize("hasAuthority('sys:user:update')")
	@OperationLog(event = "更新用户信息",operType = OperationTypeEnum.UPDATE)
	public Result update(@Validated @RequestBody SysUser sysUser) {
		sysUserService.updateById(sysUser);
		return Result.succ(sysUser);
	}

	@Transactional
	@PostMapping("/delete")
	//todo DeleteMapping 传入数组接收不到参数
	@PreAuthorize("hasAuthority('sys:user:delete')")
	@OperationLog(event = "删除用户",operType = OperationTypeEnum.DELETE)
	public Result delete(@RequestBody Long[] ids) {

		sysUserService.removeByIds(Arrays.asList(ids));
		sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id", ids));

		return Result.succ("");
	}

	@Transactional
	@PostMapping("/role/{userId}")
	@PreAuthorize("hasAuthority('sys:user:role')")
	@OperationLog(event = "分配权限",operType = OperationTypeEnum.UPDATE)
	public Result rolePerm(@PathVariable("userId") Long userId, @RequestBody Long[] roleIds) {

		List<SysUserRole> userRoles = new ArrayList<>();

		Arrays.stream(roleIds).forEach(r -> {
			SysUserRole sysUserRole = new SysUserRole();
			sysUserRole.setRoleId(r);
			sysUserRole.setUserId(userId);

			userRoles.add(sysUserRole);
		});

		sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
		sysUserRoleService.saveBatch(userRoles);

		// 删除缓存
		SysUser sysUser = sysUserService.getById(userId);
		sysUserService.clearUserAuthorityInfo(sysUser.getUsername());

		return Result.succ("");
	}

	@PutMapping("/repass")
	@PreAuthorize("hasAuthority('sys:user:repass')")
	@OperationLog(event = "重置密码",operType = OperationTypeEnum.UPDATE)
	public Result repass(@RequestParam("id") Long userId) {
		SysUser sysUser = sysUserService.getById(userId);
		sysUser.setPassword(passwordEncoder.encode(defaultPassword));
		sysUserService.updateById(sysUser);
		return Result.succ(null);
	}

	@PostMapping("/updatePass")
	@OperationLog(event = "更新密码",operType = OperationTypeEnum.UPDATE,isSaveRequestData = false)
	public Result updatePass(@Validated @RequestBody PassDto passDto, Principal principal) {

		SysUser sysUser = sysUserService.getByUsername(principal.getName());

		boolean matches = passwordEncoder.matches(passDto.getCurrentPass(), sysUser.getPassword());
		if (!matches) {
			return Result.fail("旧密码不正确");
		}

		sysUser.setPassword(passwordEncoder.encode(passDto.getPassword()));
//		sysUser.setUpdated(LocalDateTime.now());

		sysUserService.updateById(sysUser);
		return Result.succ("");
	}
}
